/* 
● ?.  (可选链操作符)
  ○ 语法: 表达式?.xxx  |  表达式?.()
  ○ 左侧表达式的值可能是undefined或null, 或者可能不存在时, 结果为undefined, 不会抛出错误
*/

interface State {
  name?: string;
  fn?: () => {}
}

let s: State|undefined

console.log(s?.name, s?.fn?.()); // undefined undefined

/* 
● ?? (空值合并操作符)
  ○  语法: 表达式1 ?? 表达式2
  ○ 用于在左侧操作数为 null 或 undefined 时，返回右侧操作数的值，否则返回左侧操作数的值。
  ○ 区别于||: 左边操作数对应的boolean值为false时，返回右侧操作数的值，否则返回左侧操作数的值。
*/

let name2 = null ?? "A"; // "A"
let age2 = undefined ?? 18; // 18
let title2 = "CEO" ?? "Employee"; // "CEO"
let aa = 0 ?? 'xxxx'    // 0
console.log(name2, age2, title2)

/* 
● ! (非空断言操作符)
  ○ 语法: 表达式! 
  ○ 告诉 TS编译器，左侧表达式不会为 null 或 undefined，从而避免编译器报告错误。
*/
const container = document.getElementById("container")!;
container.textContent = "Hello!";

/* 
● !. (非空断言链操作符)
  ○ 表达式!.xxx = value
  ○ 断言表达式不会为 null 或 undefined, 整个表达式可以可以被赋值
  ○ ?.的表达式只能读取, 不能被赋值
*/
const container2 = document.getElementById("container");
container2!.textContent = "Hello!";